﻿using Jacobi.Vst.Core;
using Jacobi.Vst.Framework.Plugin;
using Levfier.GUI;
using Levfier.Proccessors;

namespace Levfier
{
    /// <summary>
    /// This class manages the plugin audio processing.
    /// </summary>
    internal class AudioProcessor : VstPluginAudioProcessorBase
    {
        /// <summary>
        /// 入力チャネル数
        /// </summary>
        private static readonly int inputNum = 2;

        /// <summary>
        /// 出力チャネル数
        /// </summary>
        private static readonly int outputNum = 2;

        /// <summary>
        /// プラグインのルート
        /// </summary>
        private FxPluginRoot _plugin;

        /// <summary>
        /// 初期化済みか否か
        /// </summary>
        private bool isInit;

        /// <summary>
        /// アンプ
        /// </summary>
        private Amplifier amp;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="plugin">プラグイン</param>
        public AudioProcessor(FxPluginRoot plugin)
            : base(inputNum, outputNum, 0)
        {
            this.isInit = false;
            this._plugin = plugin;
            this.amp = new Amplifier();
        }

        /// <summary>
        /// サンプルレート
        /// </summary>
        public override float SampleRate
        {
            get { return (float)VSTParameterManager.GetInstance().SampleRate; }
            set { VSTParameterManager.GetInstance().SampleRate = value; }
        }

        /// <summary>
        /// Perform audio processing on the specified <paramref name="inChannels"/> 
        /// and produce a delay effect on the <paramref name="outChannels"/>.
        /// </summary>
        /// <param name="inChannels">The audio input buffers.</param>
        /// <param name="outChannels">The audio output buffers.</param>
        public override void Process(VstAudioBuffer[] inChannels, VstAudioBuffer[] outChannels)
        {
            //初期化
            if (!this.isInit)
            {
                VSTParameterManager.GetInstance().SampleCount = inChannels[0].SampleCount;
                this.amp.InitInputStream(inChannels);
                this.amp.InitOutputStream(outChannels);
                if (null != _plugin.Window)
                {
                    _plugin.Window.SetAmplifier(this.amp);
                    this.isInit = true;
                }
            }

            ///サンプルカウントに変更があれば、内部で自動的にイベントを発生する。
            VSTParameterManager.GetInstance().SampleCount = outChannels[0].SampleCount;

            //入力チャネル -> ストリーム
            this.amp.CopyFromInput(inChannels);

            //処理する
            this.amp.Proccess();

            //ストリーム -> 出力チャネル
            this.amp.CopyToOutput(outChannels);
        }
    }
}
